package com.dm.cloud.auth.controller.auth;

import java.util.HashMap;
import java.util.Map;

import cn.hutool.core.util.StrUtil;
import com.dm.cloud.auth.service.AuthPermissionService;
import com.dm.cloud.auth.service.AuthUserService;
import com.dm.cloud.core.config.CommonConstants;
import com.dm.cloud.core.exception.CustomException;
import com.dm.cloud.core.mode.ResultModel;
import com.dm.cloud.core.mode.UserMode;
import com.dm.cloud.oauthlib.service.anon.HasLogin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.oauth2.config.SaOAuth2Config;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Handle;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.stp.StpUtil;

import javax.servlet.http.HttpServletRequest;

/**
 * Sa-OAuth2 Server端 控制器
 *
 * @author click33
 */
@RestController
public class SaOAuth2ServerController {

    @Autowired
    private AuthUserService userService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private AuthPermissionService authPermissionService;

    // 处理所有OAuth相关请求
    @RequestMapping("/oauth2/*")
    public Object request(HttpServletRequest request) {
        System.out.println(request.getRequestURI());
        System.out.println("------- 进入请求: " + SaHolder.getRequest().getUrl());
        Object re = SaOAuth2Handle.serverRequest();
        return re;
    }

    // Sa-OAuth2 定制化配置
    @Autowired
    public void setSaOAuth2Config(SaOAuth2Config cfg) {
        cfg.setNotLoginView(() -> {
            // 未登录的视图
            return new ModelAndView("login.html");
        }).setDoLoginHandle((name, pwd) -> {
            String role=SaHolder.getRequest().getParam("role");
            if(StrUtil.isEmpty(role)){
                return new CustomException("请选择角色",401,null);
            }
            UserMode userMode=userService.login(name,pwd,role);
            return ResultModel.success("登录成功！");
        }).setConfirmView((clientId, scope) -> {
            // 授权确认视图
            Map<String, Object> map = new HashMap<>();
            map.put("clientId", clientId);
            map.put("scope", scope);
            return new ModelAndView("confirm.html", map);
        });
    }

    // ---------- 开放相关资源接口： Client端根据 Access-Token ，置换相关资源 ------------
    // 获取Userinfo信息：昵称、头像、性别等等
    @GetMapping("/oauth2/userinfo")
    @HasLogin
    public ResultModel userinfo() {
        String token = request.getHeader(CommonConstants.AUTH_HEAD_KEY);
        // 获取 Access-Token 对应的账号id
        Object loginId = SaOAuth2Util.getLoginIdByAccessToken(token);
        // 校验 Access-Token 是否具有权限: userinfo
        Object user = StpUtil.getSessionByLoginId(loginId).get(CommonConstants.AUTH_USER_DETAIL);
        if(user==null){
            throw new CustomException("用户信息过期，请重新登录！");
        }
        UserMode userMode=(UserMode) user;
        userMode.setPermissions(authPermissionService.findUserPermissionsByRoleIds(userMode.getRoles()));
        return ResultModel.success(user);
    }

    @GetMapping("/oauth2/logout")
    @HasLogin
    public ResultModel logout() {
        String token = request.getHeader(CommonConstants.AUTH_HEAD_KEY);
        try {
            // 获取 Access-Token 对应的账号id
            Object loginId = SaOAuth2Util.getLoginIdByAccessToken(token);
            StpUtil.logout(loginId);
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResultModel.success();
    }

}
